package com.ayf.payment.game.api.controller.platform;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.cache.redis.RedisCacheUtil;
import com.ayf.payment.game.api.channel.ChannelHandleFactory;
import com.ayf.payment.game.api.config.SystemInitialization;
import com.ayf.payment.game.api.dto.platform.*;
import com.ayf.payment.game.api.dto.platform.criteria.MerchantCashOutCriteria;
import com.ayf.payment.game.api.dto.platform.criteria.MerchantCashOutPageCriteria;
import com.ayf.payment.game.api.dto.platform.criteria.MerchantSettleDayListDTO;
import com.ayf.payment.game.api.entity.platform.MerchantCashOut;
import com.ayf.payment.game.api.exception.ExcelException;
import com.ayf.payment.game.api.exception.ParameterException;
import com.ayf.payment.game.api.service.platform.MerchantCashOutService;
import com.ayf.payment.game.api.type.CommonConstants;
import com.ayf.payment.game.api.type.ExportType;
import com.ayf.payment.game.api.type.MerchantPayOrderStatusEnum;
import com.ayf.payment.game.api.utils.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.swwx.charm.commons.lang.utils.BeanConvertUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 提现结算
 *
 * @author wwl
 * @date 2020/3/11 14:13
 */
@RequestMapping("/t")
@RestController
public class MerchantCashOutController {
    @Autowired
    private MerchantCashOutService merchantCashOutService;

    @Autowired
    private RedisCacheUtil redisCacheUtil;

    @Resource
    private SystemInitialization systemInitialization;

    @Autowired
    private ChannelHandleFactory channelHandleFactory;

    /**
     * 提现审核列表   OK
     * @param selectPageCriteria
     * @return
     */
    @PostMapping("/cashOut/selectVerifyAll")
    public CommonResult<MerchantCashOutCountDTO> selectVerifyAll(@RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria=new MerchantCashOutCriteria();
        selectCriteria.setTradeStatus(0);
        selectCriteria.setMerchantId(selectPageCriteria.getMerchantId());
        selectCriteria.setCardNo(selectPageCriteria.getCardNo());
        selectCriteria.setStratTime(selectPageCriteria.getStratTime());
        selectCriteria.setEndTime(selectPageCriteria.getEndTime());
        selectCriteria.setIsAtuoSettle(selectPageCriteria.getIsAtuoSettle());
        selectCriteria.setSettleTypes(selectPageCriteria.getSettleTypes());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantCashOutAll(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        PageHelper.startPage(selectPageCriteria.getPageNum(), selectPageCriteria.getPageSize());
        selectPageCriteria.setTradeStatus(0);
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAll(selectPageCriteria);
        PageInfo pageInfo = new PageInfo(list);
        dto.setPageInfo(pageInfo);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", dto);
    }

    /**
     * 结算付款确认列表
     * @param selectPageCriteria
     * @return
     */
    @PostMapping("/cashOut/selectConfirmAll")
    public CommonResult<MerchantCashOutCountDTO> selectConfirmAll(@RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria=new MerchantCashOutCriteria();
        selectCriteria.setTradeStatus(2);
        selectCriteria.setMerchantId(selectPageCriteria.getMerchantId());
        selectCriteria.setCardNo(selectPageCriteria.getCardNo());
        selectCriteria.setSettleTypes(selectPageCriteria.getSettleTypes());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantCashOutAll(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        PageHelper.startPage(selectPageCriteria.getPageNum(), selectPageCriteria.getPageSize());
        selectPageCriteria.setTradeStatus(2);
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAll(selectPageCriteria);
        PageInfo pageInfo = new PageInfo(list);
        dto.setPageInfo(pageInfo);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", dto);
    }

    /**
     * 付款记录列表
     * @param selectPageCriteria
     * @return
     */
    @PostMapping("/cashOut/selectMerchantCashOutAll")
    public CommonResult<MerchantCashOutCountDTO> selectMerchantCashOutAll(@RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria = BeanConvertUtils.convert(selectPageCriteria, MerchantCashOutCriteria.class);
        selectCriteria.setTradeStatus(3);
        if (selectPageCriteria.getQueryTimeType() !=null && 1==selectPageCriteria.getQueryTimeType()){ // 按照完成时间查询
            Date startTime = selectPageCriteria.getStratTime();
            Date endTime = selectPageCriteria.getEndTime();
            selectCriteria.setStratTime(null);
            selectCriteria.setEndTime(null);
            selectCriteria.setStratFinishTime(startTime);
            selectCriteria.setEndFinishTime(endTime);
            selectPageCriteria.setStratFinishTime(startTime);
            selectPageCriteria.setEndFinishTime(endTime);
            selectPageCriteria.setStratTime(null);
            selectPageCriteria.setEndTime(null);
        }
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantCashOutAll(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        PageHelper.startPage(selectPageCriteria.getPageNum(), selectPageCriteria.getPageSize());
        if(selectPageCriteria.getTradeStatus()==null) {
            List<Integer> defaultTradeStatusList = new ArrayList<>();
            defaultTradeStatusList.add(Integer.valueOf(1));
            defaultTradeStatusList.add(Integer.valueOf(3));
            defaultTradeStatusList.add(Integer.valueOf(4));
            defaultTradeStatusList.add(Integer.valueOf(5));
            selectPageCriteria.setTradeStatusList(defaultTradeStatusList);
        }
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAll(selectPageCriteria);
        PageInfo pageInfo = new PageInfo(list);
        dto.setPageInfo(pageInfo);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", dto);
    }

    /**
     * 查询批付记录列表
     * @param selectPageCriteria
     * @return
     */
    @PostMapping("/cashOut/selectBatchOrderAll")
    public CommonResult<PageInfo> selectBatchOrderAll(@RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        List<Integer> defaultTradeStatusList = new ArrayList<>();
        defaultTradeStatusList.add(Integer.valueOf(1));
        defaultTradeStatusList.add(Integer.valueOf(3));
        defaultTradeStatusList.add(Integer.valueOf(4));
        defaultTradeStatusList.add(Integer.valueOf(5));
        selectPageCriteria.setTradeStatusList(defaultTradeStatusList);
        List<MerchantCashOutBatchDTO> list= merchantCashOutService.selectBatchOrderAll(selectPageCriteria);
        list.forEach((merchantCashOutBatchDTO)->{
            if(merchantCashOutBatchDTO.getSuccessCountNumber()==merchantCashOutBatchDTO.getCountNumber()){
                merchantCashOutBatchDTO.setTradeStatusStr("付款成功");
            }
            if(merchantCashOutBatchDTO.getSuccessCountNumber()<merchantCashOutBatchDTO.getCountNumber()){
                merchantCashOutBatchDTO.setTradeStatusStr("部分成功");
            }
            if(merchantCashOutBatchDTO.getSuccessCountNumber()==0){
                merchantCashOutBatchDTO.setTradeStatusStr("待付款");
            }
        });

        PageInfo pageInfo = new PageInfo(list);

        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", pageInfo);
    }

    /**
     * 查询批付明细记录
     * @param selectCriteria
     * @return
     */
    @PostMapping("/cashOut/getCashOutByBatchList")
    public CommonResult<List<MerchantCashOutDTO>> getCashOutByBatchList(@RequestBody MerchantCashOutCriteria selectCriteria) {
        List<MerchantCashOutDTO> list= merchantCashOutService.getCashOutByBatchList(selectCriteria);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", list);
    }


    /**
     * 查询需要结算列表 D+1 OK
     * @param selectPageCriteria
     * @return
     */
    @PostMapping("/settle/selectDay1All")
    public CommonResult<MerchantCashOutCountDTO> selectDay1All(@RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria=new MerchantCashOutCriteria();
        selectCriteria.setSettleCycle(1);
        selectCriteria.setMerchantId(selectPageCriteria.getMerchantId());
        selectCriteria.setStratDateIndex(selectPageCriteria.getStratDateIndex());
        selectCriteria.setEndDateIndex(selectPageCriteria.getEndDateIndex());
        selectCriteria.setSellteAmount(selectPageCriteria.getSellteAmount());
        selectCriteria.setTradeStatusList(selectPageCriteria.getTradeStatusList());
        selectCriteria.setSettleTypes(selectPageCriteria.getSettleTypes());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantSettleDay(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        PageHelper.startPage(selectPageCriteria.getPageNum(), selectPageCriteria.getPageSize());
        List<MerchantSettleDayDTO> list= merchantCashOutService.selectMerchantSettleDay1(selectPageCriteria);
        PageInfo pageInfo = new PageInfo(list);
        dto.setPageInfo(pageInfo);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", dto);
    }

    /**
     * 查询需要结算列表 D+0  OK
     * @param selectPageCriteria
     * @return
     */
    @PostMapping("/settle/selectDay0All")
    public CommonResult<MerchantCashOutCountDTO> selectDay0All(@RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria=new MerchantCashOutCriteria();
        selectCriteria.setSettleCycle(0);
        selectCriteria.setMerchantId(selectPageCriteria.getMerchantId());
        selectCriteria.setStratDateIndex(selectPageCriteria.getStratDateIndex());
        selectCriteria.setEndDateIndex(selectPageCriteria.getEndDateIndex());
        selectCriteria.setSellteAmount(selectPageCriteria.getSellteAmount());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantSettleDay(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        PageHelper.startPage(selectPageCriteria.getPageNum(), selectPageCriteria.getPageSize());
        List<MerchantSettleDayDTO> list= merchantCashOutService.selectMerchantSettleDay0(selectPageCriteria);
        PageInfo pageInfo = new PageInfo(list);
        dto.setPageInfo(pageInfo);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", dto);
    }


    /**
     * D1确认结算   OK
     * @param merchantSettleDayDTO
     * @return
     */
    @PostMapping("/settle/merchantSettleDay1")
    public CommonResult merchantSettleDay1(AdminUserDTO adminUserDTO, @RequestBody MerchantSettleDayDTO merchantSettleDayDTO) throws Exception {
        if(merchantSettleDayDTO==null ){
            throw new ParameterException("参数不能为空");
        }
        String traceId = SnowFlakeUtils.getTraceId();
        return merchantCashOutService.merchantSettleDay1(adminUserDTO.getLoginAccount(),adminUserDTO.getLoginAccount(), merchantSettleDayDTO,traceId);
    }


    /**
     * 多选D1确认结算   OK
     * @param merchantSettleDayListDTO
     * @return
     */
    @PostMapping("/settle/merchantSettleD1Group")
    public CommonResult merchantSettleD1Group(AdminUserDTO adminUserDTO, @RequestBody MerchantSettleDayListDTO merchantSettleDayListDTO) throws Exception {
         if(merchantSettleDayListDTO==null && merchantSettleDayListDTO.getSettleList().size()>0){
             throw new ParameterException("请选择结算单");
         }
         StringBuffer buffer=new StringBuffer();
         for(MerchantSettleDayDTO settleDayDTO:merchantSettleDayListDTO.getSettleList()) {
             try{
                 String traceId = SnowFlakeUtils.getTraceId();
                 CommonResult commonResult= merchantCashOutService.merchantSettleDay1(adminUserDTO.getLoginAccount(),adminUserDTO.getLoginAccount(), settleDayDTO,traceId);
                 if(commonResult.getCode()==-1){
                     buffer.append("{").append(commonResult.getMsg()).append("}");
                 }
             }catch (ParameterException e){
                 buffer.append("{").append(e.getMsg()).append("}");
             }
         }
        if(buffer.toString().equals("")) {
            return new CommonResult(CommonConstants.RETURN_SUCCESS, "确认结算", "");
        }else{
            return new CommonResult(CommonConstants.RETURN_SUCCESS, buffer.toString(), "");
        }
    }



    /**
     * 提现多选审核确认结算
     * @param merchantSettleDayListDTO
     * @return
     */
    @PostMapping("/settle/verifyMerchantSettleGroup")
    public CommonResult verifyMerchantSettleGroup(AdminUserDTO adminUserDTO, @RequestBody MerchantSettleDayListDTO merchantSettleDayListDTO){
        if(merchantSettleDayListDTO==null){
            throw new ParameterException("请选择提现待审核记录");
        }
        if(merchantSettleDayListDTO.getTradeNumbers()==null || merchantSettleDayListDTO.getTradeNumbers().length <= 0){
            throw new ParameterException("请选择提现待审核记录");
        }
        String settleOrdeCreateStr = DateUtils.dateToString(new Date(), DateUtils.formatPattern_Short);
        String settleBatchOrderNo = "B" + settleOrdeCreateStr + RandomStrUtils.createRandom(true, 8);
        Date batchTime=new Date();
        StringBuffer buffer=new StringBuffer();
        for(String tradeNumber:merchantSettleDayListDTO.getTradeNumbers()) {
            if(redisCacheUtil.hasKey("YHB_CASH_OUT_"+tradeNumber)){
                buffer.append("{").append(tradeNumber).append(":").append("提现审核重复操作").append("}");
            }else {
                try {
                    redisCacheUtil.setObjectToCache("YHB_CASH_OUT_" + tradeNumber, 0);
                    String traceId = SnowFlakeUtils.getTraceId();
                    CommonResult commonResult = merchantCashOutService.merchantSettlePayment(adminUserDTO.getLoginAccount(), tradeNumber, traceId,settleBatchOrderNo,batchTime,merchantSettleDayListDTO.getPayChannelCode(),merchantSettleDayListDTO.getCashOutType(),merchantSettleDayListDTO.getTradePwd());
                    if (commonResult.getCode()!=200){
                        buffer.append("{").append(tradeNumber).append(":").append(commonResult.getMsg()).append("}");
                    }
                }  finally {
                    if (redisCacheUtil.hasKey("YHB_CASH_OUT_" + tradeNumber)) {
                        redisCacheUtil.delete("YHB_CASH_OUT_" + tradeNumber);
                    }
                }
            }
        }
        if(buffer.toString().equals("")) {
            return new CommonResult(CommonConstants.RETURN_SUCCESS, "审核成功", "");
        }else{
            return new CommonResult(-5, buffer.toString(), "");
        }
    }

    /**
     *多选付款确认   OK
     * @param merchantSettleDayListDTO
     * @return
     */
    @PostMapping("/cashOut/confirmMerchantSettleGroup")
    public CommonResult confirmMerchantSettleGroup(AdminUserDTO adminUserDTO, @RequestBody MerchantSettleDayListDTO merchantSettleDayListDTO) {
        if(merchantSettleDayListDTO==null){
            throw new ParameterException("请选择付款单");
        }
        if(merchantSettleDayListDTO.getTradeNumbers()==null || merchantSettleDayListDTO.getTradeNumbers().length<=0){
            throw new ParameterException("请选择付款单");
        }
        String settleOrdeCreateStr = DateUtils.dateToString(new Date(), DateUtils.formatPattern_Short);
        String settleBatchOrderNo = "B" + settleOrdeCreateStr + RandomStrUtils.createRandom(true, 8);
        Date batchTime=new Date();
        StringBuffer buffer=new StringBuffer();
        for(String tradeNumber:merchantSettleDayListDTO.getTradeNumbers()) {
            if(redisCacheUtil.hasKey("YHB_CASH_OUT_"+tradeNumber)){
                buffer.append("{").append(tradeNumber).append(":").append("付款确认重复操作").append("}");
            }else {
                try {
                    redisCacheUtil.setObjectToCache("YHB_CASH_OUT_" + tradeNumber, 0);
                    String traceId = SnowFlakeUtils.getTraceId();
                    CommonResult commonResult = merchantCashOutService.merchantSettlePayment(adminUserDTO.getLoginAccount(), tradeNumber, traceId,settleBatchOrderNo,batchTime,merchantSettleDayListDTO.getPayChannelCode(),merchantSettleDayListDTO.getCashOutType(),merchantSettleDayListDTO.getTradePwd());
                    if (-1==commonResult.getCode()){
                        buffer.append("{").append(tradeNumber).append(":").append(commonResult.getMsg()).append("}");
                    }
                }  finally {
                    if (redisCacheUtil.hasKey("YHB_CASH_OUT_" + tradeNumber)) {
                        redisCacheUtil.delete("YHB_CASH_OUT_" + tradeNumber);
                    }
                }
            }
        }
        if(buffer.toString().equals("")) {
            return new CommonResult(CommonConstants.RETURN_SUCCESS, "付款成功", "");
        }else{
            return new CommonResult(-5, buffer.toString(), "");
        }

    }

    /**
     *多选拒绝提现  OK
     * @param merchantSettleDayListDTO
     * @return
     */
    @PostMapping("/cashOut/refuseMerchantVerifyGroup")
    public CommonResult refuseMerchantVerifyGroup(AdminUserDTO adminUserDTO, @RequestBody MerchantSettleDayListDTO merchantSettleDayListDTO) throws Exception {
        if(merchantSettleDayListDTO==null){
            throw new ParameterException("参数不能为空");
        }

        if(merchantSettleDayListDTO.getTradeNumbers()==null && merchantSettleDayListDTO.getTradeNumbers().length>0){
            throw new ParameterException("参数ID不能为空");
        }
        StringBuffer buffer=new StringBuffer();
        for(String tradeNumber:merchantSettleDayListDTO.getTradeNumbers()) {
            try {
                String traceId = SnowFlakeUtils.getTraceId();
                merchantCashOutService.updateRefuseMerchantVerify(adminUserDTO.getLoginAccount(),tradeNumber,traceId);
            }catch (ParameterException e){
                buffer.append("{").append(tradeNumber).append(":").append(e.getMsg()).append("}");
            }
        }
        if(buffer.toString().equals("")) {
            return new CommonResult(CommonConstants.RETURN_SUCCESS, "成功", "");
        }else{
            return new CommonResult(CommonConstants.RETURN_SUCCESS, buffer.toString(), "");
        }
    }

    /**
     *多选拒绝付款  OK
     * @param merchantSettleDayListDTO
     * @return
     */
    @PostMapping("/cashOut/refuseMerchantSettleGroup")
    public CommonResult refuseMerchantSettleGroup(AdminUserDTO adminUserDTO, @RequestBody MerchantSettleDayListDTO merchantSettleDayListDTO) throws Exception {
        if(merchantSettleDayListDTO==null){
            throw new ParameterException("参数不能为空");
        }

        if(merchantSettleDayListDTO.getTradeNumbers()==null && merchantSettleDayListDTO.getTradeNumbers().length>0){
            throw new ParameterException("参数ID不能为空");
        }
        StringBuffer buffer=new StringBuffer();
        for(String tradeNumber:merchantSettleDayListDTO.getTradeNumbers()) {
            try {
                String traceId = SnowFlakeUtils.getTraceId();
                merchantCashOutService.updateRefuseMerchantPayment(adminUserDTO.getLoginAccount(),tradeNumber,traceId);
            }catch (ParameterException e){
                buffer.append("{").append(tradeNumber).append(":").append(e.getMsg()).append("}");

            }
        }
        if(buffer.toString().equals("")) {
            return new CommonResult(CommonConstants.RETURN_SUCCESS, "成功", "");
        }else{
            return new CommonResult(CommonConstants.RETURN_SUCCESS, buffer.toString(), "");
        }
    }

    /**
     * 获取提现记录用户信息  OK
     * @param merchantSettleDayDTO
     * @return
     */
   @PostMapping("/cashOut/getMerchantCashOut")
   public CommonResult<MerchantSettleDayDTO> getMerchantCashOutByTradeNumber(@RequestBody MerchantSettleDayDTO merchantSettleDayDTO){
       if(merchantSettleDayDTO.getTradeNumber()==null){
           throw new ParameterException("参数ID不能为空");
       }
       MerchantCashOut merchantCashOut= merchantCashOutService.getMerchantCashOutByTradeNumber(merchantSettleDayDTO.getTradeNumber());
       MerchantSettleDayDTO db=new MerchantSettleDayDTO();
       db.setTradeNumber(merchantCashOut.getTradeNumber());
       db.setCardNo(merchantCashOut.getCardNo());
       db.setBankName(merchantCashOut.getBankName());
       db.setBankBranchName(merchantCashOut.getBankBranchName());
       db.setBankCity(merchantCashOut.getBankCity());
       db.setAccountName(merchantCashOut.getAccountName());
       db.setSettleType(merchantCashOut.getSettleType());
       return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", db);
   }

    /**
     * 修改提现记录用户信息  OK
     * @param merchantSettleDayDTO
     * @return
     */
    @PostMapping("/cashOut/updateMerchantCashOut")
    public CommonResult updateMerchantCashOutByTradeNumber(@RequestBody MerchantSettleDayDTO merchantSettleDayDTO){
        if(merchantSettleDayDTO.getTradeNumber()==null){
            throw new ParameterException("流水号不能为空");
        }
        if(merchantSettleDayDTO.getCardNo()==null){
            throw new ParameterException("银行卡号不能为空");
        }
        if(merchantSettleDayDTO.getBankName()==null){
            throw new ParameterException("银行名称能为空");
        }
        if(merchantSettleDayDTO.getAccountName()==null){
            throw new ParameterException("收款人不能为空");
        }
        if(merchantSettleDayDTO.getSettleType()==null){
            throw new ParameterException("账户类型不能为空");
        }
        merchantCashOutService.updateMerchantCashOutByTradeNumber(merchantSettleDayDTO);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "成功", "");
    }


    @PostMapping(value = "/settle/merchantSettleD0Export")
    public void merchantSettleD0Export(HttpServletResponse response, @RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria=new MerchantCashOutCriteria();
        selectCriteria.setSettleCycle(0);
        selectCriteria.setMerchantId(selectPageCriteria.getMerchantId());
        selectCriteria.setStratDateIndex(selectPageCriteria.getStratDateIndex());
        selectCriteria.setEndDateIndex(selectPageCriteria.getEndDateIndex());
        selectCriteria.setSellteAmount(selectPageCriteria.getSellteAmount());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantSettleDay(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        if (dto.getCountNumber()==0){
            MyReturnJsonUtil.printErrMsg(response,"记录不存在，不能导出");
            return;
        }
        List<MerchantSettleDayDTO> list= merchantCashOutService.selectMerchantSettleDay0(selectPageCriteria);

        List<List<MerchantSettleDayDTO>> list2 = new ArrayList<>();
        int size = 5000;
        int num = list.size() % size == 0 ? list.size() / size : list.size() / size + 1;
        for (int i = 0; i < num; i++) {
            List<MerchantSettleDayDTO> subList = list.subList(i * size, i == num - 1 ? list.size() : (i + 1) * size);
            list2.add(subList);
        }
        try {
            Map<String, Exchange> exchange = new HashMap<>();
            LinkedHashMap<String, String> fieldName = new LinkedHashMap<>();
            fieldName.put("merchantId", "商户ID");
            fieldName.put("accountName", "收款人");
            fieldName.put("bankName", "银行");
            fieldName.put("cardNo", "银行卡号");
            fieldName.put("settleType", "结算类型");
            fieldName.put("sellteAmount", "已结算金额");
            fieldName.put("settleStatus", "结算状态");
            fieldName.put("orderGenerateFmt", "结算日期");
            exchange.put("settleType", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("1".equals(oldValue)) {
                        return "结算到银行卡";
                    } else if ("0".equals(oldValue)) {
                        return "结算到可提现金额";
                    }else {
                        return "线下结算";
                    }
                }
            });
            exchange.put("settleStatus", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("0".equals(oldValue)) {
                        return "待结算";
                    } else {
                        return "已结算";
                    }
                }
            });

            List appendSummaryList = new LinkedList();
            appendSummaryList.add(dto.getCountNumber());
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountSellteAmount()==null? BigDecimal.ZERO:dto.getCountSellteAmount()));

            ExcelUtils.listToExcelZip(list2, fieldName, "D0结算列表", 65535, size, response,
                    "D0结算列表" + DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01),appendSummaryList, exchange,ExportType.MERCHANT_SETTLE_LIST_D0);
        } catch (ExcelException e) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} D0结算列表导出异常信息是:",e,traceId);
            MyReturnJsonUtil.printErrMsg(response,"导出失败，请联系技术支持，错误码:"+traceId);
            return;
        }
    }

    @PostMapping(value = "/settle/merchantSettleD1Export")
    public void merchantSettleD1Export(HttpServletResponse response, @RequestBody MerchantCashOutPageCriteria selectPageCriteria) {
        MerchantCashOutCriteria selectCriteria=new MerchantCashOutCriteria();
        selectCriteria.setSettleCycle(1);
        selectCriteria.setMerchantId(selectPageCriteria.getMerchantId());
        selectCriteria.setStratDateIndex(selectPageCriteria.getStratDateIndex());
        selectCriteria.setEndDateIndex(selectPageCriteria.getEndDateIndex());
        selectCriteria.setSellteAmount(selectPageCriteria.getSellteAmount());
        selectCriteria.setSettleTypes(selectPageCriteria.getSettleTypes());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantSettleDay(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        if (dto.getCountNumber()==0){
            MyReturnJsonUtil.printErrMsg(response,"记录不存在，不能导出");
            return;
        }
        List<MerchantSettleDayDTO> list= merchantCashOutService.selectMerchantSettleDay1(selectPageCriteria);

        List<List<MerchantSettleDayDTO>> list2 = new ArrayList<>();
        int size = 5000;
        int num = list.size() % size == 0 ? list.size() / size : list.size() / size + 1;
        for (int i = 0; i < num; i++) {
            List<MerchantSettleDayDTO> subList = list.subList(i * size, i == num - 1 ? list.size() : (i + 1) * size);
            list2.add(subList);
        }
        try {
            Map<String, Exchange> exchange = new HashMap<>();
            LinkedHashMap<String, String> fieldName = new LinkedHashMap<>();
            fieldName.put("merchantId", "商户ID");
            fieldName.put("accountName", "收款人");
            fieldName.put("bankName", "银行");
            fieldName.put("cardNo", "银行卡号");
            fieldName.put("settleType", "结算类型");
            fieldName.put("tradeNumber", "结算单号");
            fieldName.put("settleStatus", "结算状态");
            fieldName.put("sellteAmount", "待结算金额");
            fieldName.put("orderGenerateFmt", "结算日期");
            exchange.put("settleType", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("1".equals(oldValue)) {
                        return "结算到银行卡";
                    } else if ("0".equals(oldValue)) {
                        return "结算到可提现金额";
                    }else {
                        return "线下结算";
                    }
                }
            });
            exchange.put("settleStatus", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("0".equals(oldValue)) {
                        return "待结算";
                    } else {
                        return "已结算";
                    }
                }
            });
            List appendSummaryList = new LinkedList();
            appendSummaryList.add(dto.getCountNumber());
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountSellteAmount()==null? BigDecimal.ZERO:dto.getCountSellteAmount()));
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountNoSellteAmount()==null? BigDecimal.ZERO:dto.getCountNoSellteAmount()));
            ExcelUtils.listToExcelZip(list2, fieldName, "D1结算列表", 65535, size, response,
                    "D1结算列表" + DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01),appendSummaryList, exchange,ExportType.MERCHANT_SETTLE_LIST_D1);
        } catch (ExcelException e) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} D1结算列表导出异常信息是:",e,traceId);
            MyReturnJsonUtil.printErrMsg(response,"导出失败，请联系技术支持，错误码:"+traceId);
            return;
        }
    }

    /**
     * 申请提现列表导出
     * @param response
     * @param selectCriteria
     */
    @PostMapping(value = "/settle/merchantApplyCashOutExport")
    public void merchantApplyCashOutExport(HttpServletResponse response, @RequestBody MerchantCashOutCriteria selectCriteria) {
        selectCriteria.setTradeStatus(0);
        selectCriteria.setMerchantId(selectCriteria.getMerchantId());
        selectCriteria.setCardNo(selectCriteria.getCardNo());
        selectCriteria.setStratTime(selectCriteria.getStratTime());
        selectCriteria.setEndTime(selectCriteria.getEndTime());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantCashOutAll(selectCriteria);

        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        if (dto.getCountNumber()==0){
            MyReturnJsonUtil.printErrMsg(response,"记录不存在，不能导出");
            return;
        }
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAllNoPage(selectCriteria);

        list.forEach((merchantCashOutDTO)->{
            merchantCashOutDTO.setFmtTimeStr(DateUtils.dateToIntegerst(merchantCashOutDTO.getCreateTime(),DateUtils.formatPattern_full));
        });

        List<List<MerchantCashOutDTO>> list2 = new ArrayList<>();
        int size = 5000;
        int num = list.size() % size == 0 ? list.size() / size : list.size() / size + 1;
        for (int i = 0; i < num; i++) {
            List<MerchantCashOutDTO> subList = list.subList(i * size, i == num - 1 ? list.size() : (i + 1) * size);
            list2.add(subList);
        }
        try {
            Map<String, Exchange> exchange = new HashMap<>();
            LinkedHashMap<String, String> fieldName = new LinkedHashMap<>();
            fieldName.put("merchantId", "商户ID");
            fieldName.put("accountName", "收款人");
            fieldName.put("bankName", "银行");
            fieldName.put("cardNo", "银行卡号");
            fieldName.put("amount", "审请金额");
            fieldName.put("fee", "手续费");
            fieldName.put("actualAmount", "实付金额");
            fieldName.put("fmtTimeStr", "申请请日期");

            List appendSummaryList = new LinkedList();
            appendSummaryList.add(dto.getCountNumber());
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountSellteAmount()==null? BigDecimal.ZERO:dto.getCountSellteAmount()));
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountFee()==null? BigDecimal.ZERO:dto.getCountFee()));
            ExcelUtils.listToExcelZip(list2, fieldName, "提现申请列表", 65535, size, response,
                    "提现申请列表" + DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01),appendSummaryList, exchange,ExportType.MERCHANT_CASH_OUR_LIST);
        } catch (ExcelException e) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} 提现申请列表导出异常信息是:",e,traceId);
            MyReturnJsonUtil.printErrMsg(response,"导出失败，请联系技术支持，错误码:"+traceId);
            return;
        }
    }

    /**
     * 结算付款确认列表导出
     * @param response
     * @param selectCriteria
     */
    @PostMapping(value = "/settle/selectConfirmAllExport")
    public void selectConfirmAllExport(HttpServletResponse response, @RequestBody MerchantCashOutCriteria selectCriteria) {
        selectCriteria.setTradeStatus(2);
        selectCriteria.setMerchantId(selectCriteria.getMerchantId());
        selectCriteria.setCardNo(selectCriteria.getCardNo());
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantCashOutAll(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        if (dto.getCountNumber()==0){
            MyReturnJsonUtil.printErrMsg(response,"记录不存在，不能导出");
            return;
        }
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAllNoPage(selectCriteria);

        list.forEach((merchantCashOutDTO)->{
            merchantCashOutDTO.setFmtTimeStr(DateUtils.dateToIntegerst(merchantCashOutDTO.getCreateTime(),DateUtils.formatPattern_full));
        });

        List<List<MerchantCashOutDTO>> list2 = new ArrayList<>();
        int size = 5000;
        int num = list.size() % size == 0 ? list.size() / size : list.size() / size + 1;
        for (int i = 0; i < num; i++) {
            List<MerchantCashOutDTO> subList = list.subList(i * size, i == num - 1 ? list.size() : (i + 1) * size);
            list2.add(subList);
        }
        try {
            Map<String, Exchange> exchange = new HashMap<>();
            LinkedHashMap<String, String> fieldName = new LinkedHashMap<>();
            fieldName.put("tradeNumber", "流水号");
            fieldName.put("merchantId", "商户ID");
            fieldName.put("accountName", "收款人");
            fieldName.put("bankName", "银行");
            fieldName.put("cardNo", "银行卡号");
            fieldName.put("amount", "审请金额");
            fieldName.put("fee", "手续费");
            fieldName.put("actualAmount", "实付金额");
            fieldName.put("fmtTimeStr", "申请日期");

            List appendSummaryList = new LinkedList();
            appendSummaryList.add(dto.getCountNumber());
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountSellteAmount()==null? BigDecimal.ZERO:dto.getCountSellteAmount()));
            appendSummaryList.add(new DecimalFormat("#0.00").format(dto.getCountFee()==null? BigDecimal.ZERO:dto.getCountFee()));
            ExcelUtils.listToExcelZip(list2, fieldName, "待付款列表", 65535, size, response,
                    "待付款列表" + DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01),appendSummaryList, exchange,ExportType.MERCHANT_CASH_OUR_LIST);
        } catch (ExcelException e) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} 待付款列表导出异常信息是:",e,traceId);
            MyReturnJsonUtil.printErrMsg(response,"导出失败，请联系技术支持，错误码:"+traceId);
            return;
        }
    }


    /**
     *  批付明细导出
     * @param response
     * @param selectCriteria
     */
    @PostMapping(value = "/settle/selectBatchOrderDetailExport")
    public void selectBatchOrderDetailExport(HttpServletResponse response, @RequestBody MerchantCashOutCriteria selectCriteria) {
        SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
        List<MerchantCashOutDTO> list= merchantCashOutService.getCashOutByBatchList(selectCriteria);
        List<List<MerchantCashOutDTO>> list2 = new ArrayList<>();
        int size = 5000;
        int num = list.size() % size == 0 ? list.size() / size : list.size() / size + 1;
        for (int i = 0; i < num; i++) {
            List<MerchantCashOutDTO> subList = list.subList(i * size, i == num - 1 ? list.size() : (i + 1) * size);
            list2.add(subList);
        }
        try {
            Map<String, Exchange> exchange = new HashMap<>();
            LinkedHashMap<String, String> fieldName = new LinkedHashMap<>();
            fieldName.put("createTime", "申请时间");
            fieldName.put("tradeNumber", "流水号");
            fieldName.put("merchantId", "商户ID");
            fieldName.put("actualAmount", "付款金额");
            fieldName.put("accountName", "收款人");
            fieldName.put("cashOutType", "结算类型");
            fieldName.put("settleType", "账户类型");
            fieldName.put("bankName", "银行");
            fieldName.put("cardNo", "卡号");
            fieldName.put("tradeStatus", "状态");
            exchange.put("createTime", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (StringUtils.isEmpty(oldValue)) {
                        return null;
                    }
                    try {
                        Date date = sdf.parse(oldValue);
                        return DateUtils.dateToString(date);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    return "";
                }
            });
            exchange.put("cashOutType", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("1".equals(oldValue)) {
                        return "结算到银行卡";
                    } else if ("2".equals(oldValue)) {
                        return "线下转账";
                    }
                    return "";
                }
            });
            exchange.put("settleType", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("0".equals(oldValue)) {
                        return "银行卡";
                    } else if ("1".equals(oldValue)) {
                        return "支付宝";
                    }
                    return "";
                }
            });
            exchange.put("tradeStatus", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("4".equals(oldValue)) {
                        return "付款失败";
                    } else if ("3".equals(oldValue)) {
                        return "付款成功";
                    }else if ("1".equals(oldValue)) {
                        return "拒绝付款";
                    }else if ("5".equals(oldValue)) {
                        return "通道处理中";
                    }
                    return "";
                }
            });
            ExcelUtils.listToExcelZip(list2, fieldName, "批付明细导出", 65535, size, response,
                    "批付明细导出" + DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01),null, exchange,null);
        } catch (ExcelException e) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} 批付明细导出异常信息是:",e,traceId);
            MyReturnJsonUtil.printErrMsg(response,"批付明细导出失败，请联系技术支持，错误码:"+traceId);
            return;
        }
    }

    /**
     * 付款列表导出
     * @param response
     * @param selectCriteria
     */
    @PostMapping(value = "/settle/selectMerchantCashOutExport")
    public void selectMerchantCashOutExport(HttpServletResponse response, @RequestBody MerchantCashOutCriteria selectCriteria) {
        if (selectCriteria.getQueryTimeType() !=null && 1==selectCriteria.getQueryTimeType()){ // 按照完成时间查询
            Date startTime = selectCriteria.getStratTime();
            Date endTime = selectCriteria.getEndTime();
            selectCriteria.setStratFinishTime(startTime);
            selectCriteria.setEndFinishTime(endTime);
            selectCriteria.setStratTime(null);
            selectCriteria.setEndTime(null);
        }
        MerchantCashOutCountDTO dto=merchantCashOutService.countMerchantCashOutAll(selectCriteria);
        if(null ==dto){
            dto=new MerchantCashOutCountDTO();
        }
        if (dto.getCountNumber()==0){
            MyReturnJsonUtil.printErrMsg(response,"记录不存在，不能导出");
            return;
        }
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAllNoPage(selectCriteria);
        list.forEach((merchantCashOutDTO)->{
            merchantCashOutDTO.setFmtTimeStr(DateUtils.dateToIntegerst(merchantCashOutDTO.getCreateTime(),DateUtils.formatPattern_full));
        });
        List<List<MerchantCashOutDTO>> list2 = new ArrayList<>();
        int size = 5000;
        int num = list.size() % size == 0 ? list.size() / size : list.size() / size + 1;
        for (int i = 0; i < num; i++) {
            List<MerchantCashOutDTO> subList = list.subList(i * size, i == num - 1 ? list.size() : (i + 1) * size);
            list2.add(subList);
        }
        try {
            Map<String, Exchange> exchange = new HashMap<>();
            LinkedHashMap<String, String> fieldName = new LinkedHashMap<>();
            fieldName.put("tradeNumber", "流水号");
            fieldName.put("merchantId", "商户ID");
            fieldName.put("accountName", "收款人");
            fieldName.put("bankName", "银行");
            fieldName.put("cardNo", "银行卡号");
            fieldName.put("amount", "审请金额");
            fieldName.put("fee", "手续费");
            fieldName.put("actualAmount", "实付金额");
            fieldName.put("fmtTimeStr", "申请日期");

            exchange.put("tradeStatus", new Exchange() {
                @Override
                public String exchange(String oldValue) {
                    if (oldValue == null) {
                        return null;
                    }
                    if ("4".equals(oldValue)) {
                        return "付款失败";
                    } else {
                        return "付款成功";
                    }
                }
            });


            ExcelUtils.listToExcelZip(list2, fieldName, "付款列表", 65535, size, response,
                    "付款列表" + DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01),null, exchange, null);
        } catch (ExcelException e) {
            String traceId = SnowFlakeUtils.getTraceId();
            LogPortal.error("{} 付款列表导出异常信息是:",e,traceId);
            MyReturnJsonUtil.printErrMsg(response,"导出失败，请联系技术支持，错误码:"+traceId);
            return;
        }
    }

    /**
     * 获取结算手续费
     * @param selectCriteria
     * @return
     */
    @PostMapping("/settle/getFee")
    public CommonResult<BigDecimal> settleGetFee(@RequestBody MerchantCashOutCriteria selectCriteria) {
        SettleConfigDTO settleConfigDTO = systemInitialization.settleConfigDTO();
        BigDecimal merchantFee = MerchantSettleServiceChargeUtil.getServiceCharge(selectCriteria.getMerchantId(), selectCriteria.getSellteAmount(),settleConfigDTO.getFeeCustom());
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "获取结算手续费成功",merchantFee);
    }


    /**
     * 支付云代付文件导出
     */
    @PostMapping(value = "/zfyAgentPayExport")
    public void orderExport(HttpServletResponse response, @RequestBody MerchantCashOutCriteria selectCriteria) {
        if (CollUtil.isEmpty(selectCriteria.getTradeNumberList())){
            throw new ParameterException("至少选择一条订单");
        }
        MerchantCashOutCriteria merchantCashOutCriteria = new MerchantCashOutCriteria();
        merchantCashOutCriteria.setTradeNumberList(selectCriteria.getTradeNumberList());
        List<MerchantCashOutDTO> list= merchantCashOutService.selectMerchantCashOutAllNoPage(merchantCashOutCriteria);
        list.parallelStream().forEach(item->{item.setAccountTypeName("个人");item.setPayDesc("分润");});
        String traceId = SnowFlakeUtils.getTraceId();
        String date = DateUtils.dateToString(new Date(), DateUtils.formatPattern_full_01);
        try {
            com.ayf.payment.game.api.excel.ExcelUtils.listFillExport(traceId, list, "支付云代付" + date + ".xlsx", "zfy_agent_pay.xlsx", response);
        } catch (Exception e) {
            LogPortal.error("{} 导出失败,异常信息是:[{}]", e, traceId, e.getMessage());
        }
    }

    @PostMapping("/settle/settleAgentPayOrderQuery")
    public CommonResult<?> settleAgentPayOrderQuery(@RequestBody MerchantCashOutCriteria selectCriteria) {
        JSONObject inputParam = new JSONObject();
        String traceId = SnowFlakeUtils.getTraceId();
        inputParam.put("traceId",traceId);
        inputParam.put("channelCode",selectCriteria.getPayChannelCode());
        inputParam.put("merchant_order_no",selectCriteria.getTradeNumber());
        inputParam.put("substitutePayConfigId",selectCriteria.getPayChannelId());
        JSONObject data =channelHandleFactory.getHandler(inputParam.getString("channelCode")).orderQuery(inputParam);
        if (data == null){
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "通道处理中",null);
        }
        Integer status = data.getInteger("status");
        if (status == null || MerchantPayOrderStatusEnum.PAY_PROCESSING.getStatus().equals(status)){
            return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "通道处理中",null);
        }
        MerchantCashOutDTO merchantCashOutDTO = new MerchantCashOutDTO();
        merchantCashOutDTO.setTradeNumber(selectCriteria.getTradeNumber());
        String channelOrderNo = data.getString("channelOrderNo");
        if (StringUtils.isNotEmpty(channelOrderNo)){
            merchantCashOutDTO.setChannelOrderNo(channelOrderNo);
        }
        if (MerchantPayOrderStatusEnum.PAY_SUCCESS.getStatus().equals(status)){
            merchantCashOutDTO.setTradeStatus(Short.valueOf("3"));
        } else if (MerchantPayOrderStatusEnum.PAY_FAIL.getStatus().equals(status)){
            String failReason = data.getString("failReason");
            merchantCashOutDTO.setReturnMsg(failReason);
            merchantCashOutDTO.setTradeStatus(Short.valueOf("4"));
        }
        merchantCashOutDTO.setTraceId(traceId);
        merchantCashOutService.updateSettleAgentPayOrderStatus(merchantCashOutDTO);
        return new CommonResult<>(CommonConstants.RETURN_SUCCESS, "通道处理完成",null);
    }

}
